<template>
    <div class="uploader">
        <slot :file-list="fileList" :files="files" :started="started">
            <uploader-unsupport></uploader-unsupport>
            <uploader-drop>
                <p>Drop files here to upload or</p>
                <uploader-btn>select files</uploader-btn>
                <uploader-btn :directory="true">select folder</uploader-btn>
            </uploader-drop>
            <uploader-list></uploader-list>
        </slot>
    </div>
</template>

<script>
import Uploader from '../../simple-uploader/uploader'
import {kebabCase} from '../common/utils'
import UploaderBtn from './btn.vue'
import UploaderDrop from './drop.vue'
import UploaderUnsupport from './unsupport.vue'
import UploaderList from './list.vue'
import UploaderFiles from './files.vue'
import UploaderFile from './file.vue'

const COMPONENT_NAME = 'uploader'
const FILE_ADDED_EVENT = 'fileAdded'
const FILES_ADDED_EVENT = 'filesAdded'
const UPLOAD_START_EVENT = 'uploadStart'
const FILE_DUPLICATE_EVENT = 'fileDuplicate'

export default {
    name: COMPONENT_NAME,
    provide() {
        return {
            uploader: this
        }
    },
    props: {
        options: {
            type: Object,
            default() {
                return {}
            }
        },
        autoStart: {
            type: Boolean,
            default: true
        },
        fileStatusText: {
            type: [Object, Function],
            default() {
                return {
                    success: 'success',
                    error: 'error',
                    uploading: 'uploading',
                    paused: 'paused',
                    waiting: 'waiting'
                }
            }
        }
    },
    data() {
        return {
            started: false,
            files: [],
            fileList: []
        }
    },
    methods: {
        uploadStart() {
            this.started = true
        },
        fileAdded(file) {
            this.$emit(kebabCase(FILE_ADDED_EVENT), file)
            if (file.ignored) {
                // is ignored, filter it
                return false
            }
        },
        fileDuplicate(file){
            this.$Message.warning("文件"+file.name+"重复")
        },
        filesAdded(files, fileList) {
            this.$emit(kebabCase(FILES_ADDED_EVENT), files, fileList)
            if (files.ignored || fileList.ignored) {
                // is ignored, filter it
                return false
            }
        },
        fileRemoved(file) {
            this.files = this.uploader.files
            this.fileList = this.uploader.fileList
        },
        filesSubmitted(files, fileList) {
            this.files = this.uploader.files
            this.fileList = this.uploader.fileList
            if (this.autoStart) {
                this.uploader.upload()
            }
        },
        allEvent(...args) {
            const name = args[0]
            const EVENTSMAP = {
                [FILE_ADDED_EVENT]: true,
                [FILES_ADDED_EVENT]: true,
                [UPLOAD_START_EVENT]: 'uploadStart',
                [FILE_DUPLICATE_EVENT]: 'fileDuplicate'
            }
            const handler = EVENTSMAP[name]
            if (handler) {
                if (handler === true) {
                    return
                }
                this[handler].apply(this, args.slice(1))
            }
            args[0] = kebabCase(name)
            this.$emit.apply(this, args)
        }
    },
    created() {
        this.options.initialPaused = !this.autoStart
        const uploader = new Uploader(this.options)
        this.uploader = uploader
        this.uploader.fileStatusText = this.fileStatusText
        uploader.on('catchAll', this.allEvent)
        uploader.on(FILE_ADDED_EVENT, this.fileAdded)
        uploader.on(FILES_ADDED_EVENT, this.filesAdded)
        uploader.on('fileRemoved', this.fileRemoved)
        uploader.on('filesSubmitted', this.filesSubmitted)
    },
    destroyed() {
        const uploader = this.uploader
        uploader.off('catchAll', this.allEvent)
        uploader.off(FILE_ADDED_EVENT, this.fileAdded)
        uploader.off(FILES_ADDED_EVENT, this.filesAdded)
        uploader.off('fileRemoved', this.fileRemoved)
        uploader.off('filesSubmitted', this.filesSubmitted)
        this.uploader = null
    },
    components: {
        UploaderBtn,
        UploaderDrop,
        UploaderUnsupport,
        UploaderList,
        UploaderFiles,
        UploaderFile
    }
}
</script>

<style>
.uploader {
    position: relative;
}
</style>
